#include "stdafx.h"
#include "HttpDownloader.h"
#include <QNetworkRequest>
#include <QDebug>
#include <QFileInfo>

HttpDownloader::HttpDownloader(QObject* parent)
    : QObject(parent)
    , m_manager(new QNetworkAccessManager(this))
    , m_reply(nullptr)
    , m_file(nullptr)
    , m_speedTimer(new QTimer(this))
    , m_totalSize(0)
    , m_downloadedSize(0)
    , m_lastDownloadedSize(0)
    , m_currentSpeed(0)
    , m_isPaused(false)
{
    connect(m_speedTimer, &QTimer::timeout, this, &HttpDownloader::updateSpeed);
}

HttpDownloader::~HttpDownloader()
{
    cancelDownload();
}

void HttpDownloader::startDownload(const QString& url, const QString& filePath)
{
    if (isDownloading()) {
        emit errorOccurred("已有下载任务正在进行");
        return;
    }

    m_url = url;
    m_filePath = filePath;
    m_isPaused = false;

    // 创建文件
    m_file = new QFile(filePath);
    if (!m_file->open(QIODevice::WriteOnly)) {
        emit errorOccurred("无法创建文件: " + filePath);
        delete m_file;
        m_file = nullptr;
        return;
    }

    // 创建网络请求
    QNetworkRequest request(QUrl(url));
  //  request.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");

    // 支持断点续传
    QFileInfo fileInfo(filePath);
    if (fileInfo.exists() && fileInfo.size() > 0) {
        qint64 existingSize = fileInfo.size();
      //  request.setRawHeader("Range", QString("bytes=%1-").arg(existingSize).toUtf8());
        m_downloadedSize = existingSize;
    }
    else {
        m_downloadedSize = 0;
    }

    m_reply = request.get(request);

    // 连接信号槽
    connect(m_reply, &QNetworkReply::readyRead, this, &HttpDownloader::onReadyRead);
    connect(m_reply, &QNetworkReply::downloadProgress, this, &HttpDownloader::onDownloadProgress);
    connect(m_reply, &QNetworkReply::finished, this, &HttpDownloader::onFinished);
    connect(m_reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
        this, &HttpDownloader::onError);

    // 启动速度计时器
    m_lastDownloadedSize = m_downloadedSize;
    m_downloadTimer.start();
    m_speedTimer->start(1000);

    emit statusChanged("开始下载");
    qDebug() << "开始下载:" << url;
}

void HttpDownloader::pauseDownload()
{
    if (m_reply && m_reply->isRunning()) {
        m_reply->abort();
        m_isPaused = true;
        m_speedTimer->stop();
        emit statusChanged("下载已暂停");
    }
}

void HttpDownloader::resumeDownload()
{
    if (m_isPaused && m_file && m_file->isOpen()) {
        startDownload(m_url, m_filePath);
    }
}

void HttpDownloader::cancelDownload()
{
    if (m_reply) {
        m_reply->abort();
        m_reply->deleteLater();
        m_reply = nullptr;
    }

    if (m_file) {
        if (m_file->isOpen()) {
            m_file->close();
        }
        // 取消下载时删除不完整文件
        m_file->remove();
        m_file->deleteLater();
        m_file = nullptr;
    }

    m_speedTimer->stop();
    m_isPaused = false;
    emit statusChanged("下载已取消");
}

bool HttpDownloader::isDownloading() const
{
    return m_reply && m_reply->isRunning();
}

qint64 HttpDownloader::getDownloadedSize() const
{
    return m_downloadedSize;
}

qint64 HttpDownloader::getTotalSize() const
{
    return m_totalSize;
}

double HttpDownloader::getProgress() const
{
    if (m_totalSize > 0) {
        return (static_cast<double>(m_downloadedSize) / m_totalSize) * 100.0;
    }
    return 0.0;
}

QString HttpDownloader::getSpeed() const
{
    return formatSpeed(static_cast<qint64>(m_currentSpeed));
}

void HttpDownloader::onReadyRead()
{
    if (m_reply && m_file && m_file->isOpen()) {
        QByteArray data = m_reply->readAll();
        qint64 bytesWritten = m_file->write(data);
        if (bytesWritten != data.size()) {
            emit errorOccurred("文件写入错误");
            cancelDownload();
        }
    }
}

void HttpDownloader::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
    m_downloadedSize = m_downloadedSize + bytesReceived;
    m_totalSize = bytesTotal > 0 ? bytesTotal : 0;

    double percentage = getProgress();
    emit progressChanged(percentage, m_downloadedSize, m_totalSize);

    qDebug() << "下载进度:" << percentage << "%" << m_downloadedSize << "/" << m_totalSize;
}

void HttpDownloader::onFinished()
{
    m_speedTimer->stop();

    if (!m_reply) {
        return;
    }

    bool success = false;
    QString message;

    if (m_reply->error() == QNetworkReply::NoError) {
        // 写入剩余数据
        if (m_file && m_file->isOpen()) {
            QByteArray remainingData = m_reply->readAll();
            if (!remainingData.isEmpty()) {
                m_file->write(remainingData);
            }
            m_file->close();
        }

        success = true;
        message = "下载完成: " + m_filePath;
        emit statusChanged("下载完成");
        qDebug() << "下载成功:" << m_filePath;
    }
    else if (m_isPaused) {
        // 暂停状态，不视为错误
        success = false;
        message = "下载已暂停";
    }
    else {
        if (m_file) {
            m_file->close();
        }
        success = false;
        message = "下载失败: " + m_reply->errorString();
        emit statusChanged("下载失败");
        qDebug() << "下载失败:" << m_reply->errorString();
    }

    if (!m_isPaused) {
        m_reply->deleteLater();
        m_reply = nullptr;

        if (m_file) {
            m_file->deleteLater();
            m_file = nullptr;
        }
    }

    emit finished(success, message);
}

void HttpDownloader::onError(QNetworkReply::NetworkError code)
{
    Q_UNUSED(code)
        if (!m_isPaused) {
            emit errorOccurred(m_reply->errorString());
        }
}

void HttpDownloader::updateSpeed()
{
    qint64 currentBytes = m_downloadedSize;
    qint64 bytesDiff = currentBytes - m_lastDownloadedSize;
    m_currentSpeed = bytesDiff / (m_downloadTimer.restart() / 1000.0);
    m_lastDownloadedSize = currentBytes;

    emit speedUpdated(getSpeed());
}

void HttpDownloader::reset()
{
    cancelDownload();
    m_totalSize = 0;
    m_downloadedSize = 0;
    m_lastDownloadedSize = 0;
    m_currentSpeed = 0;
    m_isPaused = false;
}

QString HttpDownloader::formatSpeed(qint64 bytesPerSecond)
{
    if (bytesPerSecond < 1024) {
        return QString("%1 B/s").arg(bytesPerSecond);
    }
    else if (bytesPerSecond < 1024 * 1024) {
        return QString("%1 KB/s").arg(bytesPerSecond / 1024.0, 0, 'f', 1);
    }
    else {
        return QString("%1 MB/s").arg(bytesPerSecond / (1024.0 * 1024.0), 0, 'f', 1);
    }
}

QString HttpDownloader::formatSize(qint64 bytes)
{
    if (bytes < 1024) {
        return QString("%1 B").arg(bytes);
    }
    else if (bytes < 1024 * 1024) {
        return QString("%1 KB").arg(bytes / 1024.0, 0, 'f', 1);
    }
    else if (bytes < 1024 * 1024 * 1024) {
        return QString("%1 MB").arg(bytes / (1024.0 * 1024.0), 0, 'f', 1);
    }
    else {
        return QString("%1 GB").arg(bytes / (1024.0 * 1024.0 * 1024.0), 0, 'f', 1);
    }
}